package com.zcm.springbootwebsocket.ws;

import com.alibaba.fastjson.JSON;
import com.sun.org.slf4j.internal.Logger;
import com.sun.org.slf4j.internal.LoggerFactory;
import com.zcm.springbootwebsocket.common.MessageUtils;
import com.zcm.springbootwebsocket.config.WebSocketConfig;
import com.zcm.springbootwebsocket.entity.ChatMessage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Zhang Dapao
 * @date 2022/4/9
 */
@ServerEndpoint(value = "/chat",configurator = WebSocketConfig.class)
@Component
@Slf4j
public class ChatEndpoint {
    //静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
    private static volatile int onlineCount = 0;

    //用来存储每个客户端对应EndPoint 对象
    private static ConcurrentHashMap<String, ChatEndpoint> concurrentHashMap=new ConcurrentHashMap<>();

    //声明session对象，由于每个链接都需要一个session对象 所以不定义为静态
    private Session session;

    //声明HttpSession对象
    private HttpSession httpSession;

    @OnOpen
    public void onOpen(Session session, EndpointConfig config){
        this.session=session;
        HttpSession httpSession = (HttpSession)config.getUserProperties().get(HttpSession.class.getName());
        this.httpSession=httpSession;
        String username = (String) httpSession.getAttribute("user");
        //将对象存入容器
        concurrentHashMap.put(username,this);
        addOnlineCount();
        //将当前在线用户的用户民推送给所有的客户端
        String message = MessageUtils.getMessage(true, null, getName());
        //消息推送
        sendMessage(message,null);
        log.info("用户连接:"+username+",当前在线人数为:" + getOnlineCount());
    }

    @OnMessage
    public void OnMessage(String message,Session session){
        if (message.equals("again")){
            sendxt();
            return;
        }
        //将meaasge转成实体类对象
        ChatMessage chatMessage = JSON.parseObject(message, ChatMessage.class);
        //发送给的用户
        String toName = chatMessage.getToName();
        //获取消息数据
        String msg = chatMessage.getMessage();
        //获取当前登录的用户
        String username = (String)httpSession.getAttribute("user");
        String res = MessageUtils.getMessage(false, username, msg);
        sendMessage(res, toName);
    }
    @OnClose
    public void OnClose(Session session, CloseReason closeReason){
        String username = (String) httpSession.getAttribute("user");
        concurrentHashMap.remove(username);
        subOnlineCount();
        log.info("用户连接:"+username+",当前在线人数为:" + getOnlineCount());
        String message = MessageUtils.getMessage(true, null, getName());
        sendMessage(message,null);
    }
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("出错了！");
        error.printStackTrace();
    }
    private void sendxt(){
        this.session.getAsyncRemote().sendText("success");
    }
    private void sendMessage(String message, String string){
        Set<String> names = concurrentHashMap.keySet();
        //全局广播
        if (StringUtils.isBlank(string)){
            names.forEach(name->{
                ChatEndpoint chatEndpoint = concurrentHashMap.get(name);
                chatEndpoint.session.getAsyncRemote().sendText(message);
            });
        }else{
            ChatEndpoint endpoint = concurrentHashMap.get(string);
            endpoint.session.getAsyncRemote().sendText(message);
        }
    }

    private Set<String> getName(){
       return concurrentHashMap.keySet();
    }

    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        onlineCount--;
    }
}
